package cn.duckerkj.cacheclean;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * js clean cache
 * @author Shensg
 * 2018年7月9日
 * 
 * 
 * 仅作为JS缓存 可以扩展为CSS
 * 修改注解和返回contentType
 * 
 * 更新策略
 * 访问同一个文件次数大于100次则101次拿最新的数据 暂时硬编码  
 * 配合max-age一同使用。60s内取流浪器本地缓存不会请求
 * 组合使用为大于更新时间并且访问次数大于100次 则获取文件数据
 */
@WebServlet(urlPatterns = {
		"*.js","*.html","*.css"
})
public class MyDefaultServlet extends HttpServlet{
	private static final long serialVersionUID = 1L;
	/*
	 * 存放文件数据和文件名称
	 * */	
	HashMap<String, byte[]> hashMap = new HashMap<String, byte[]>();
	/**
	 * 访问文件访问次数
	 */
	HashMap<String, Integer> urlCount = new HashMap<String, Integer>();
	
	protected void service(HttpServletRequest request,HttpServletResponse response) throws IOException  {
		//拿出文件数据
		byte[] bytes=hashMap.get(request.getRequestURI().toString());
		//数据为空为第一次访问,需要把数据拿出来存放到内存中，反之则内存中依旧有数据，直接取出来
		if (bytes == null) {
			//得到当前路径
			File file=new File(this.getServletContext().getRealPath("."));
			//组合成访问文件所在路径
			file=new File(file.getParentFile(),request.getRequestURI().toString());
			System.out.println(file.getPath());
			//读取文件数据,将文件数据存放到内存中
			FileInputStream fin=null;
			try {
				fin = new FileInputStream(file);
				bytes = new byte[(int) file.length()];
				fin.read(bytes);
				hashMap.put(request.getRequestURI().toString(), bytes);
			} catch (FileNotFoundException e) {
				//存入 避免再次 类似redis穿透理念
				bytes = "404 No Source File".getBytes();
				hashMap.put(request.getRequestURI().toString(), bytes);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
				if(fin != null) {
					fin.close();
				}
			}
		}
		//缓存策略 
		int count = urlCount.get(request.getRequestURI().toString())!=null?urlCount.get(request.getRequestURI().toString()):0;
		count++;
		urlCount.put(request.getRequestURI().toString(),count);
		if(count>100) {
			hashMap.remove(request.getRequestURI().toString());
			urlCount.remove(request.getRequestURI().toString());
		}
		
		//后缀判断类型
		if(request.getRequestURI().toString().endsWith(".css")) {
			response.setContentType("text/css; charset=UTF-8");
		}
		if(request.getRequestURI().toString().endsWith(".js")) {
			response.setContentType("text/javascript; charset=UTF-8");
		}
		if(request.getRequestURI().toString().endsWith(".html")) {
			response.setContentType("text/html; charset=UTF-8");
		}
		//设置静态资源过期时间
		response.addHeader("Cache-Control", "max-age=60");
		
		OutputStream outputStream = null;
		try {
			//输出到浏览器中
			outputStream = response.getOutputStream();
			outputStream.write(bytes);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if (outputStream != null) {
				outputStream.close();
			}
		}
		
	}
}
